package v1

import (
	"encoding/json"
	"sweetsunnyflower/app/models/chat"
	"sweetsunnyflower/pkg/jwt"
	"sweetsunnyflower/pkg/logger"
	"sweetsunnyflower/pkg/websocket"
	"sync"

	"github.com/spf13/cast"
)

type WebsocketController struct {
}

var websocketController *WebsocketController

var once sync.Once

// 返回消息结构
type Payload struct {
	Type    uint64 `json:"type"`
	Message string `json:"message"`
	Target  string `json:"target"`
}

func GetWebsocketController() *WebsocketController {
	once.Do(func() {
		websocketController = new(WebsocketController)
	})
	return websocketController
}

func Distribute(client *websocket.Client, content *websocket.Content) {
	c := GetWebsocketController()
	switch content.Action {
	case "ping":
		c.Pong(client, content)

	case "chat":
		c.Chat(client, content)

	case "online":
		c.Online(client, content)
	}

}

func (c *WebsocketController) Pong(client *websocket.Client, content *websocket.Content) {
	client.Send <- []byte(Format("pong", content))
}

func (c *WebsocketController) Online(client *websocket.Client, content *websocket.Content) {

	onlineCount := len(websocket.NewClientManager().ClientMap)

	client.Send <- []byte(Format("online", onlineCount))
}

func (c *WebsocketController) Chat(client *websocket.Client, content *websocket.Content) {

	token := content.Token

	t, err := jwt.NewJWT().ParseStringToken(token)

	if err != nil {
		logger.Error(err.Error())
		return
	}

	// 消息入库
	chatModel := &chat.Chat{
		UserID:  cast.ToUint64(t.UserID),
		Type:    content.Payload.Type,
		Content: content.Payload.Content,
		ToID:    0,
	}

	chatModel.Save()

	if chatModel.ID > 0 {
		// 广播内容
		websocket.NewClientManager().Broadcast(Format("replay", chat.GetByID(chatModel.ID)), websocket.TextMessage, nil)
	}
}

func Format(action string, content interface{}) string {

	responseContent := new(websocket.ResponseContent)

	str, _ := json.Marshal(content)

	responseContent.Action = action

	responseContent.Payload = string(str)

	data, _ := json.Marshal(responseContent)

	return string(data)
}
